package com.zmn.oms.third.core.interfaces;

import com.zmn.oms.common.enums.ChannelFacade;
import com.zmn.oms.common.exception.chan.ChannelFacadeException;
import com.zmn.oms.common.exception.chan.DuplicateOrderClueException;
import com.zmn.oms.model.dto.order.proxy.OrderLogDTO;
import com.zmn.oms.model.entity.chan.FacadeMessageEvent;
import com.zmn.oms.model.entity.chan.FacadeMessageEventError;
import com.zmn.oms.model.entity.chan.OrderClue;
import com.zmn.oms.model.entity.work.OrderWorkLogChange;
import com.zmn.oms.third.pinduoduo.dto.api.PinDuoDuoResponse;

/**
 * 类描述：渠道接入的最外层业务支持接口
 *
 * @author lhl
 * @date 2020/12/31 16:02
 */
public interface ChannelFacadeBService {

    /**
     * 新建新单线索
     * @param event
     * @param outerId 渠道订单ID
     * @param generateFacadeOrderId 是否生成需要返回给渠道方的啄木鸟订单ID，如果为 true，生成的ID将在方法调用结束后保存在 orderClue 参数对象的 facadeOrderId 字段中
     * @return
     * @throws DuplicateOrderClueException 当判定该线索为重复收到时被抛出，判定条件为：channelFacade 和 outerId 组合值是否唯一
     * @throws ChannelFacadeException 当保存失败时被抛出
     */
    OrderClue createOrderClue(FacadeMessageEvent event,
                              String outerId,
                              boolean generateFacadeOrderId) throws DuplicateOrderClueException, ChannelFacadeException;

    /**
     * 新建新单线索
     * @param event
     * @param outerId 渠道订单ID
     * @param generateFacadeOrderId 是否生成需要返回给渠道方的啄木鸟订单ID，如果为 true，生成的ID将在方法调用结束后保存在 orderClue 参数对象的 facadeOrderId 字段中
     * @param extOuterId1 第一外部扩展订单号
     * @param extOuterId2 第二外部扩展订单号
     * @return
     * @throws DuplicateOrderClueException 当判定该线索为重复收到时被抛出，判定条件为：channelFacade 和 outerId 组合值是否唯一
     * @throws ChannelFacadeException 当保存失败时被抛出
     */
    OrderClue createOrderClue(FacadeMessageEvent event,
                           String outerId,
                           boolean generateFacadeOrderId,
                           String extOuterId1,
                           String extOuterId2) throws DuplicateOrderClueException, ChannelFacadeException;

    /**
     * 获取对应的订单线索
     * @param orderClueId 订单线索主键ID
     * @return 对应的订单线索，如果没找到，返回null
     */
    OrderClue findOrderClueByOrderClueId(Long orderClueId);

    /**
     * 收到订单的业务消息，保存消息并获取对应的订单线索
     * @param event 该对象的 facadeId、tag、content 字段不能为null
     * @param outerId 渠道订单号
     * @param channelId 渠道订单号
     * @return 对应的订单线索
     * @throws ChannelFacadeException 当未找到对应的订单线索或保存消息失败时被抛出
     */
    OrderClue receiveOrderBizMessage(FacadeMessageEvent event, String outerId, Integer channelId)
            throws ChannelFacadeException;
    /**
     * 收到非订单消息，保存消息
     * @param event
     * @throws ChannelFacadeException 当保存消息失败时被抛出
     */
    void receiveNonOrderMessage(FacadeMessageEvent event) throws ChannelFacadeException;

    /**
     * 发送渠道门户消息事件
     * @param facadeMessageEvent
     */
    void sendFacadeMessageEvent(FacadeMessageEvent facadeMessageEvent);

    /**
     * 保存渠道门户消息事件错误
     * @param facadeMessageEvent
     * @param errorMsg
     */
    void saveFacadeMessageEventError(FacadeMessageEvent facadeMessageEvent, String errorMsg);

    /**
     * 保存自定义订单操作日志
     *  使用示例：
     *      OrderLogDTO orderLogDTO = new OrderLogDTO();
     *      orderLogDTO.setOrderId(orderId);
     *      orderLogDTO.setOperatorLogRemark(remark);
     *      this.saveCustomOrderLog(orderLogDTO);
     * @param orderLogDTO
     */
    void saveCustomOrderLog(OrderLogDTO orderLogDTO);

    /**
     * 保存状态同步结果信息
     * @param orderWorkLogChange
     * @param orderStatus
     * @param result
     * @return void
     * @author wangxiaokun
     */
    void saveSyncResult(OrderWorkLogChange orderWorkLogChange, int orderStatus, PinDuoDuoResponse result);
}
